package com.seu.project.seuquiz.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.seu.project.seuquiz.common.ErrorCode;
import com.seu.project.seuquiz.constant.CommonConstant;
import com.seu.project.seuquiz.exception.BusinessException;
import com.seu.project.seuquiz.model.dto.user.UserQueryRequest;
import com.seu.project.seuquiz.model.entity.CollegeContestMap;
import com.seu.project.seuquiz.model.entity.User;
import com.seu.project.seuquiz.service.UserService;
import com.seu.project.seuquiz.mapper.UserMapper;
import com.seu.project.seuquiz.constant.UserConstant;
import com.seu.project.seuquiz.util.SqlUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.util.Strings;
import org.springframework.stereotype.Service;
import org.springframework.util.DigestUtils;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

import java.util.Date;

import static com.seu.project.seuquiz.constant.UserConstant.MIN_PASSWORD_LENGTH;

/**
* @author 林怀旭
* @description 针对表【user(用户)】的数据库操作Service实现
* @createDate 2023-05-15 10:37:01
*/
@Service
@Slf4j
public class UserServiceImpl extends ServiceImpl<UserMapper, User>
    implements UserService {

    @Resource
    private UserMapper userMapper;

    /**
     * 盐值，混淆密码
     */
    private static final String SALT="linhuaixu";

    private static final String EMAIL_EXPR = "^[a-z0-9A-Z]+[- | a-z0-9A-Z . _]+@([a-z0-9A-Z]+(-[a-z0-9A-Z]+)?\\.)+[a-z]{2,}$";

    @Override
    public long userRegister(String studentID,String email, String college, String major, String userPassword, String checkPassword) {
        //1.校验
        if(StringUtils.isAnyBlank(studentID, email, college, major, userPassword,checkPassword)){
            throw new BusinessException(ErrorCode.PARAMS_ERROR,"参数为空");
        }
        if(studentID.length()<4){
            throw new BusinessException(ErrorCode.PARAMS_ERROR,"用户学号过短");
        }
        if (!email.matches(EMAIL_EXPR)) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "邮箱非法");
        }
        if(userPassword.length()<MIN_PASSWORD_LENGTH || checkPassword.length()<MIN_PASSWORD_LENGTH){
            throw new BusinessException(ErrorCode.PARAMS_ERROR,"用户密码过短");
        }
        //密码和校验密码相同
        if(!userPassword.equals(checkPassword)){
            throw new BusinessException(ErrorCode.PARAMS_ERROR,"两次输入密码不一致");
        }
        synchronized (studentID.intern()){
            //学号不能重复
            QueryWrapper<User> queryWrapper=new QueryWrapper<>();
            queryWrapper.eq("studentID",studentID);
            long count=userMapper.selectCount(queryWrapper);
            if(count>0){
                throw new BusinessException(ErrorCode.PARAMS_ERROR,"账号重复");
            }
            //2.加密
            String encryptPassword= DigestUtils.md5DigestAsHex((SALT+userPassword).getBytes());
            //3.插入数据
            User user=new User();
            user.setStudentID(studentID);
            user.setEmail(email);
            user.setCollege(college);
            user.setMajor(major);
            user.setUserPassword(encryptPassword);
            boolean save = this.save(user);
            if(!save){
                throw new BusinessException(ErrorCode.SYSTEM_ERROR,"注册失败，数据库错误");
            }
            return user.getId();
        }
    }

    @Override
    public User userLogin(String studentID, String userPassword, HttpServletRequest request) {
        //1.校验
        if(StringUtils.isAnyBlank(studentID,userPassword)){
            throw new BusinessException(ErrorCode.PARAMS_ERROR,"参数为空");
        }
        if(studentID.length()<4){
            throw new BusinessException(ErrorCode.PARAMS_ERROR,"账号错误");
        }
        if(userPassword.length()<MIN_PASSWORD_LENGTH){
            throw new BusinessException(ErrorCode.PARAMS_ERROR,"密码错误");
        }
        //2.加密
        String encryptPassword= DigestUtils.md5DigestAsHex((SALT+userPassword).getBytes());
        //3.查询用户是否存在
        QueryWrapper<User> queryWrapper=new QueryWrapper<>();
        queryWrapper.eq("studentID",studentID);
        queryWrapper.eq("userPassword",encryptPassword);
        User user = userMapper.selectOne(queryWrapper);
        if(user==null){
            log.info("用户登录失败，账号和密码不匹配");
            throw new BusinessException(ErrorCode.PARAMS_ERROR,"用户不存在或密码错误");
        }
        //4.将用户信息存入session
        request.getSession().setAttribute(UserConstant.USER_LOGIN_STATE,user);
        return user;
    }

    @Override
    public User getLoginUser(HttpServletRequest request) {
        User currentUser= (User) request.getSession().getAttribute(UserConstant.USER_LOGIN_STATE);
        if(currentUser==null || currentUser.getId()==null){
            log.info("当前用户信息为空 request.getSession().getAttribute {}", currentUser);
            throw new BusinessException(ErrorCode.NOT_LOGIN_ERROR);
        }
        Long id = currentUser.getId();
        User user = this.getById(id);
        if(user==null){
            log.info("数据库中查不到该用户信息 id {}", id);
            throw new BusinessException(ErrorCode.NOT_LOGIN_ERROR);
        }
        return currentUser;
    }

    @Override
    public boolean isAdmin(HttpServletRequest request) {
        User currentUser= (User) request.getSession().getAttribute(UserConstant.USER_LOGIN_STATE);
        return currentUser!=null && UserConstant.ADMIN_ROLE.equals(currentUser.getUserRole());
    }

    @Override
    public boolean userLogout(HttpServletRequest request) {
        if(request.getSession().getAttribute(UserConstant.USER_LOGIN_STATE)==null){
            throw new BusinessException(ErrorCode.FORBIDDEN_ERROR,"未登录");
        }
        //移除登录状态
        request.getSession().removeAttribute(UserConstant.USER_LOGIN_STATE);
        return true;
    }

    @Override
    public QueryWrapper<User> getQueryWrapper(UserQueryRequest request) {
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        if (request == null) {
            return null;
        }

        String userName = request.getUserName();
        String studentID = request.getStudentID();
        String email = request.getEmail();
        String college = request.getCollege();
        String major = request.getMajor();
        Integer gender = request.getGender();
        String userRole = request.getUserRole();
        Date createTime = request.getCreateTime();
        Date updateTime = request.getUpdateTime();
        String sortField = request.getSortField();
        String sortOrder = request.getSortOrder();

        queryWrapper.like(StringUtils.isNotBlank(userName), "userName", "%" + userName + "%");
        queryWrapper.like(StringUtils.isNotBlank(studentID), "studentID", "%" + studentID + "%");
        queryWrapper.like(StringUtils.isNotBlank(email), "email", "%" + email + "%");
        queryWrapper.like(StringUtils.isNotBlank(college), "college", "%" + college + "%");
        queryWrapper.like(StringUtils.isNotBlank(major), "major", "%" + major + "%");
        queryWrapper.eq(gender != null, "gender", gender);
        queryWrapper.like(StringUtils.isNotBlank(userRole), "userRole", "%" + userRole + "%");
        queryWrapper.orderBy(SqlUtils.validSortField(sortField), sortOrder.equals(CommonConstant.SORT_ORDER_ASC),
                sortField);

        return queryWrapper;
    }

    @Override
    public QueryWrapper<User> getEqualQueryWrapper(UserQueryRequest request) {
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        if (request == null) {
            return null;
        }

        String userName = request.getUserName();
        String studentID = request.getStudentID();
        String email = request.getEmail();
        String college = request.getCollege();
        String major = request.getMajor();
        Integer gender = request.getGender();
        String userRole = request.getUserRole();
        Date createTime = request.getCreateTime();
        Date updateTime = request.getUpdateTime();
        String sortField = request.getSortField();
        String sortOrder = request.getSortOrder();

        queryWrapper.eq(StringUtils.isNotBlank(userName), "userName", userName);
        queryWrapper.eq(StringUtils.isNotBlank(studentID), "studentID", studentID);
        queryWrapper.eq(StringUtils.isNotBlank(email), "email", email);
        queryWrapper.eq(StringUtils.isNotBlank(college), "college", college);
        queryWrapper.eq(StringUtils.isNotBlank(major), "major",  major);
        queryWrapper.eq(gender != null, "gender", gender);
        queryWrapper.eq(StringUtils.isNotBlank(userRole), "userRole", userRole);
        queryWrapper.orderBy(SqlUtils.validSortField(sortField), sortOrder.equals(CommonConstant.SORT_ORDER_ASC),
                sortField);

        return queryWrapper;
    }
}




